package com.learn.acm.netty.protobuf1;

import com.google.gson.Gson;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.util.CharsetUtil;
import lombok.extern.slf4j.Slf4j;

/**
 * 说明
 *  1.我们自定义一个Handler 需要继承netty规定好的某个HandlerAdapter
 *  2.这是我们自定义一个Handler才能称之为Handler
 */
@Slf4j
public class NettyServerHandler extends SimpleChannelInboundHandler<DataOuterClass.Data> {

    /**
     * 读取实际数据（这里我们可以读取客户端发送的消息）
     * @param ctx 上下文对象 ，含有管道pipeline，通道channel，地址信息
     * @param msg 客户端发送的数据
     * @throws Exception
     */
//    @Override
//    public void channelRead(ChannelHandlerContext ctx, DataOuterClass.Data msg) throws Exception {
//        log.info("-ctx info -->");
//        /**
//         * 将msg转换成一个ByteBuf
//         * ByteBuf是netty提供的  不是nio的ByteBuffer
//         */
//        ByteBuf byteBuf = (ByteBuf) msg;
//
//        ctx.channel().eventLoop().execute(() -> {
//            try {
//                Thread.sleep(10 * 1000);
//                ctx.writeAndFlush(Unpooled.copiedBuffer("hello 客户端~", CharsetUtil.UTF_8));
//            } catch (Exception e) {
//                log.error(e.getMessage(),e);
//            }
//        });
//
//        log.info("-客户端发送的消息是-->{}", byteBuf.toString(CharsetUtil.UTF_8));
//        log.info("-客户地址是-->{}", ctx.channel().remoteAddress());
//    }

    /**
     * 读取数据完成
     * @param ctx
     * @throws Exception
     */
    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        /**
         * writeAndFlush 是write + flush
         * 将数据写入到缓存 并刷新
         * 一般讲 我们将这个发送的数据进行编码
         */
        DataOuterClass.Data data = DataOuterClass.Data.newBuilder().setName("我是服务器").setExtend("{'a':1}").setAge(56).build();
        ctx.channel().writeAndFlush(data);
    }

    /**
     * 发生异常时 一般需要关闭通道
     * @param ctx
     * @param cause
     * @throws Exception
     */
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        cause.printStackTrace();
        ctx.close();
    }

    /**
     * <strong>Please keep in mind that this method will be renamed to
     * {@code messageReceived(ChannelHandlerContext, I)} in 5.0.</strong>
     * <p>
     *
     * @param ctx the {@link ChannelHandlerContext} which this {@link SimpleChannelInboundHandler}
     *            belongs to
     * @param msg the message to handle
     * @throws Exception is thrown if an error occurred
     */
    @Override
    protected void channelRead0(ChannelHandlerContext ctx, DataOuterClass.Data msg) throws Exception {
        log.info("--->>{}", new Gson().toJson(msg));
    }
}
